From b15505eee57b82033d7dfad15f3737bd4fa931f4 Mon Sep 17 00:00:00 2001
From: Daniel Kolesa <daniel@octaforge.org>
Date: Fri, 17 Mar 2023 19:51:20 +0100
Subject: [PATCH 1/4] general portability fixes for chimera/busyboxless
 initramfs

---
 debian/functions                         | 16 ++++-----
 debian/initramfs/conf-hooks.d/cryptsetup |  3 --
 debian/initramfs/cryptroot-unlock        | 18 +++++-----
 debian/initramfs/hooks/cryptopensc       |  9 ++---
 debian/initramfs/hooks/cryptroot         | 43 +++---------------------
 5 files changed, 27 insertions(+), 62 deletions(-)

diff --git a/debian/functions b/debian/functions
index 917abad..8758abb 100644
--- a/debian/functions
+++ b/debian/functions
@@ -20,7 +20,7 @@ cryptsetup_message() {
     elif [ ${#*} -lt 70 ]; then
         echo "cryptsetup: $*" >&2
     else
-        # use busybox's fold(1) and sed(1) at initramfs stage
+        # use fold(1) and sed(1) at initramfs stage
         echo "cryptsetup: $*" | fold -s | sed '1! s/^/    /' >&2
     fi
     return 0
@@ -450,8 +450,8 @@ crypttab_key_check() {
         fi
     fi
 
-    local mode="$(stat -L -c"%04a" -- "$CRYPTTAB_KEY")"
-    if [ $(stat -L -c"%u" -- "$CRYPTTAB_KEY") -ne 0 ] || [ "${mode%00}" = "$mode" ]; then
+    local mode="$(stat -L -f "%Mp%Lp" -- "$CRYPTTAB_KEY")"
+    if [ $(stat -L -f "%u" -- "$CRYPTTAB_KEY") -ne 0 ] || [ "${mode%00}" = "$mode" ]; then
         cryptsetup_message "WARNING: $CRYPTTAB_NAME: key file $CRYPTTAB_KEY has" \
             "insecure ownership, see /usr/share/doc/cryptsetup/README.Debian.gz."
     fi
@@ -585,10 +585,10 @@ _device_uuid() {
 _resolve_device() {
     local spec="$1" dev devno maj min
     if dev="$(_resolve_device_spec "$spec")" &&
-            devno="$(stat -L -c"%t:%T" -- "$dev" 2>/dev/null)" &&
-            maj="${devno%:*}" && min="${devno#*:}" &&
-            [ "$devno" = "$maj:$min" ] && [ -n "$maj" ] && [ -n "$min" ] &&
-            maj=$(( 0x$maj )) && min=$(( 0x$min )) && [ $maj -gt 0 ]; then
+            devno="$(stat -L -f "%Z" -- "$dev" 2>/dev/null)" &&
+            maj="${devno%,*}" && min="${devno#*,}" &&
+            [ "$devno" = "$maj,$min" ] && [ -n "$maj" ] && [ -n "$min" ] &&
+            [ $maj -gt 0 ]; then
         DEV="$dev"
         MAJ="$maj"
         MIN="$min"
@@ -670,7 +670,7 @@ _foreach_cryptdev() {
     [ "$reverse" = "y" ] && t="holders" || t="slaves"
     [ -d "$d/$t" ] || return 0
     for d2 in "$d/$t"/*; do
-        if [ -d "$d2" ] && d2="$(realpath -e -- "$d2")"; then
+        if [ -d "$d2" ] && d2="$(realpath -- "$d2")"; then
             _foreach_cryptdev "$d2"
         fi
     done
diff --git a/debian/initramfs/conf-hooks.d/cryptsetup b/debian/initramfs/conf-hooks.d/cryptsetup
index 883c1ba..f858920 100644
--- a/debian/initramfs/conf-hooks.d/cryptsetup
+++ b/debian/initramfs/conf-hooks.d/cryptsetup
@@ -2,8 +2,5 @@
 # necessary for punching in passphrases.
 KEYMAP=y
 
-# force busybox on initramfs
-BUSYBOX=y
-
 # and for systems using plymouth instead, use the new option
 FRAMEBUFFER=y
diff --git a/debian/initramfs/cryptroot-unlock b/debian/initramfs/cryptroot-unlock
index dbc2ad0..1e9cf69 100644
--- a/debian/initramfs/cryptroot-unlock
+++ b/debian/initramfs/cryptroot-unlock
@@ -1,4 +1,4 @@
-#!/bin/busybox ash
+#!/bin/sh
 
 # Remotely unlock encrypted volumes.
 #
@@ -40,7 +40,7 @@ fi
 pgrep_exe() {
 	local exe pid
 	exe="$(readlink -f -- "$1" 2>/dev/null)" && [ -f "$exe" ] || return 0
-	ps -eo pid= | while read pid; do
+	minips -eo pid= | while read pid; do
 		[ "$(readlink -f "/proc/$pid/exe")" != "$exe" ] || printf '%d\n' "$pid"
 	done
 }
@@ -101,7 +101,7 @@ wait_for_prompt() {
 			break
 		fi
 
-		usleep 100000
+		sleep 0.1
 		timer=$(( $timer - 1 ))
 		if [ $timer -le 0 ]; then
 			echo "Error: Timeout reached while waiting for askpass." >&2
@@ -130,7 +130,7 @@ wait_for_prompt() {
 	for pid in $(pgrep_exe "/sbin/cryptsetup"); do
 		if grep -Fxqz "CRYPTTAB_NAME=$CRYPTTAB_NAME" "/proc/$pid/environ"; then
 			PID=$pid
-			BIRTH=$(stat -c"%Z" "/proc/$PID" 2>/dev/null) || break
+			BIRTH=$(stat -f "%c" "/proc/$PID" 2>/dev/null) || break
 			return 0
 		fi
 	done
@@ -147,8 +147,8 @@ wait_for_prompt() {
 # failed), return with value 1.
 wait_for_answer() {
 	local timer=$(( 10 * $TIMEOUT )) b
-	while [ -d "/proc/$PID" ] && b=$(stat -c"%Z" "/proc/$PID" 2>/dev/null) && [ $b -le $BIRTH ]; do
-		usleep 100000
+	while [ -d "/proc/$PID" ] && b=$(stat -f "%c" "/proc/$PID" 2>/dev/null) && [ $b -le $BIRTH ]; do
+		sleep 0.1
 		timer=$(( $timer - 1 ))
 		if [ $timer -le 0 ]; then
 			echo "Error: Timeout reached while waiting for PID $PID." >&2
@@ -178,10 +178,12 @@ if [ -t 0 ] && [ -x "$ASKPASS" ]; then
 		# note: if the script is not killed before pivot_root it should
 		# exit on its own once $TIMEOUT is reached
 		if ! wait_for_prompt; then
-			usleep 100000
+			sleep 0.1
 			continue
 		fi
-		read -rs -p "Please unlock disk $CRYPTTAB_NAME: "; echo
+		stty -echo
+		read -r -p "Please unlock disk $CRYPTTAB_NAME: " REPLY; echo
+		stty echo
 		printf '%s' "$REPLY" >"$PASSFIFO"
 		wait_for_answer || true
 	done
diff --git a/debian/initramfs/hooks/cryptopensc b/debian/initramfs/hooks/cryptopensc
index e0c5167..bd49e84 100644
--- a/debian/initramfs/hooks/cryptopensc
+++ b/debian/initramfs/hooks/cryptopensc
@@ -46,10 +46,11 @@ mkdir -p -- "$DESTDIR/etc/opensc" "$DESTDIR/usr/lib/pcsc" "$DESTDIR/var/run" "$D
 # Install pcscd daemon, drivers, conf file
 copy_exec /usr/sbin/pcscd
 
-cp -rt "$DESTDIR/usr/lib" /usr/lib/pcsc
-cp -t "$DESTDIR/etc" /etc/reader.conf || true
-cp -t "$DESTDIR/etc" /etc/libccid_Info.plist
+cp -R /usr/lib/pcsc/* "${DESTDIR}/usr/lib/pcsc"
+cp /etc/reader.conf "${DESTDIR}/etc" || true
+cp /etc/libccid_Info.plist "${DESTDIR}/etc"
 
+# TODO chimera: fix this on musl once we have this stuff in the first place
 for so in $(ldconfig -p | sed -nr 's/^\s*(libusb-[0-9.-]+|libpcsclite)\.so\.[0-9]+\s.*=>\s*//p'); do
     copy_exec "$so"
 done
@@ -57,6 +58,6 @@ done
 # Install opensc commands and conf file
 copy_exec /usr/bin/opensc-tool
 copy_exec /usr/bin/pkcs15-crypt
-cp -t "$DESTDIR/etc/opensc" /etc/opensc/opensc.conf
+cp /etc/opensc/opensc.conf "${DESTDIR}/etc/opensc"
 
 exit $RV
diff --git a/debian/initramfs/hooks/cryptroot b/debian/initramfs/hooks/cryptroot
index 3557786..008c0af 100644
--- a/debian/initramfs/hooks/cryptroot
+++ b/debian/initramfs/hooks/cryptroot
@@ -89,7 +89,7 @@ crypttab_print_entry() {
                         [ "${keyfile#/}" != "$keyfile" ]; then
                     cryptsetup_message "WARNING: Skipping target $CRYPTTAB_NAME: key file is a symlink with absolute target"
                     return 1
-                elif [ -f "$CRYPTTAB_KEY" ] && [ "$(stat -L -c"%m" -- "$CRYPTTAB_KEY" 2>/dev/null)" != "/" ]; then
+                elif [ -f "$CRYPTTAB_KEY" ] && [ "$(findmnt -n -o TARGET --target "$CRYPTTAB_KEY" 2>/dev/null)" != "/" ]; then
                     cryptsetup_message "WARNING: Skipping target $CRYPTTAB_NAME: key file is not on the root FS"
                     return 1
                 fi
@@ -122,17 +122,6 @@ crypttab_print_entry() {
 get_resume_devno() {
     local dev filename
 
-    # uswsusp
-    for filename in /etc/uswsusp.conf /etc/suspend.conf; do
-        [ -e "$filename" ] || continue
-        dev="$(sed -nr '/^resume device\s*[:=]\s*/ {s///p;q}' "$filename")"
-        if [ -n "$dev" ] && [ "$dev" != "<path_to_resume_device_file>" ]; then
-            # trim quotes
-            dev="$(printf '%s' "$dev" | sed -re 's/^"(.*)"\s*$/\1/' -e "s/^'(.*)'\\s*$/\\1/")"
-            _print_devno "$(printf '%b' "$dev")" # unmangle
-        fi
-    done
-
     # regular swsusp
     dev="$(sed -nr 's,^(.*\s)?resume=(\S+)(\s.*)?$,\2,p' /proc/cmdline)"
     _print_devno "$(printf '%b' "$dev")" # unmangle
@@ -301,7 +290,7 @@ add_crypto_modules() {
 copy_libssl_legacy_library() {
     local libcryptodir CRYPTO_HASHES=""
 
-    libcryptodir="$(env --unset=LD_PRELOAD ldd /sbin/cryptsetup | sed -nr '/.*=>\s*(\S+)\/libcrypto\.so\..*/ {s//\1/p;q}')"
+    libcryptodir="/lib"
     [ -d "$libcryptodir" ] || return
 
     crypttab_foreach_entry populate_CRYPTO_HASHES
@@ -313,28 +302,6 @@ copy_libssl_legacy_library() {
     fi
 }
 
-# See #1032221: newer libargon2 are built with glibc ≥2.34 hence no
-# longer links libpthread.  This in turns means that initramfs-tool's
-# copy_exec() is no longer able to detect pthread_*() need and thus
-# doesn't copy libgcc_s.so anymore.  So we need to do it manually
-# instead.
-copy_libgcc_argon2() {
-    local libdir rv=0
-    libdir="$(env --unset=LD_PRELOAD ldd /sbin/cryptsetup | sed -nr '/.*=>\s*(\S+)\/libargon2\.so\..*/ {s//\1/p;q}')"
-    copy_libgcc "$libdir" || rv=$?
-    if [ $rv -ne 0 ]; then
-        # merged-/usr mismatch, see #1032518
-        if [ "${libdir#/usr/}" != "$libdir" ]; then
-            libdir="${libdir#/usr}"
-        else
-            libdir="/usr/${libdir#/}"
-        fi
-        copy_libgcc "$libdir" && rv=0 || rv=$?
-    fi
-    return $rv
-}
-
-
 #######################################################################
 # Begin real processing
 
@@ -370,14 +337,12 @@ manual_add_modules dm_crypt
 
 copy_exec /sbin/cryptsetup
 copy_exec /sbin/dmsetup
-copy_libgcc_argon2
 
 [ "$ASKPASS" = n ] || copy_exec /lib/cryptsetup/askpass
 
 # We need sed. Either via busybox or as standalone binary.
-if [ "$BUSYBOX" = n ] || [ -z "$BUSYBOXDIR" ]; then
-    copy_exec /bin/sed
-fi
+# chimera: already provided via chimerautils-tiny by default
+#copy_exec /bin/sed
 
 # detect whether the host CPU has AES-NI support
 if grep -Eq '^flags\s*:(.*\s)?aes(\s.*)?$' /proc/cpuinfo; then
-- 
2.39.0

